package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.constant.EsNormalConstant;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.pojo.dto.DeleteDTO;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.UnitEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataListSearchHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.DataDetailPojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.FormTitlePoJoSub;
import com.xbongbong.paas.pojo.PrePaymentBalanceListPojo;
import com.xbongbong.paas.pojo.ShareConditionFormatPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.SummaryExtraDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.dto.AggSumDTO;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.AggSumVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.PaymentSheetFromBalanceListVO;
import com.xbongbong.paas.pojo.vo.PrePaymentBalanceListVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.FormDataListFormExplainHandleName;
import com.xbongbong.pro.appdetail.pojo.MobileDetailDirectBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailScriptPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailSpecialInfoPojo;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.FundAccountErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.formdata.pojo.LinkBusinessSinglePojo;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.vo.FormDataDetailVO;
import com.xbongbong.pro.formdata.pojo.vo.MobileFormCommonDetailVO;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.paymentbalance.pojo.dto.PaymentSheetFromBalanceDTO;
import com.xbongbong.pro.paymentbalance.pojo.vo.PaymentSheetFromBalanceVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartQueryHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.FormHelp;
import com.xbongbong.pro.sheet.pojo.dto.SheetDeleteHandleRelateDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.PaymentBalanceInsertConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.PaymentBalanceEntity;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.MobileDetailBottomOperationEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.ManagementButtomEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceDistributorEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.ProDetailHandlerHelp;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.help.SaasPaymentSheetHelper;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.PaymentBalanceModel;
import com.xbongbong.saas.model.PaymentBalanceUserModel;
import com.xbongbong.saas.model.impl.IndexTypeModelImpl;
import com.xbongbong.saas.service.PaymentBalanceService;
import com.xbongbong.saas.service.SaasListService;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author 梁鲁江
 * @version v1.0
 * @date 2019/11/7 16:12
 * @since v1.0
 */
@Service("paymentBalanceService")
public class PaymentBalanceServiceImpl implements PaymentBalanceService {
    @Resource
    private PaymentBalanceModel paymentBalanceModel;
    @Resource
    private PaasFormModel  paasFormModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private PaymentBalanceUserModel  paymentBalanceUserModel;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private FormDataListFormExplainHandleName formDataListFormExplainHandleName;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private EsHelper esHelper;
    @Resource
    private SaasListService saasListService;
    @Resource
    private ProDetailHandlerHelp proDetailHandlerHelp;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaymentBalanceService paymentBalanceService;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private ChartQueryHelp chartQueryHelp;
    @Resource
    private FormHelp formHelp;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private SaasPaymentSheetHelper saasPaymentSheetHelper;
    public static final Logger LOG = LoggerFactory.getLogger(PaymentBalanceServiceImpl.class);
    @Resource
    private IndexTypeModelImpl indexTypeModel;

    @Override
    public void saveByPaymentSheet(PaymentSheetEntityExt paymentSheetEntityExt, Integer distributorMark) throws XbbException {
        try {
            JSONObject data = paymentSheetEntityExt.getData();
            String paymentSheetTypeStr = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
            PaymentSheetTypeEnum paymentSheetTypeEnum = PaymentSheetTypeEnum.getByCode(paymentSheetTypeStr);
            Double advancePaymentBalance;
            //只包含3种，为什么不包含“”红冲预收款核销: 直接把钱退给客户，不退回预收款余额
            switch (paymentSheetTypeEnum) {
                case PREPAYMENT:
                case RED_PREPAYMENT:
                    //红冲预收款存储的是负值可直接使用
                    advancePaymentBalance = data.getDoubleValue(PaymentSheetEnum.AMOUNT.getAttr());
                    break;
                case WRITE_OFF_PREPAYMENT:
                case RED_WRITE_OFF_BALANCE:
                    advancePaymentBalance = data.getDoubleValue(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr());
                    //核销金额要用余额减去
                    //红冲预收款核销(退到余额)，增加预收款余额，对原有负数的红冲金额乘-1即可
                    advancePaymentBalance = Arith.mul(advancePaymentBalance,-1D);
                    break;
                default:
                    LOG.error(paymentSheetTypeEnum.getAlias() + PaymentErrorCodeEnum.API_ERROR_208029.getMsg());
                    throw  new XbbException(PaymentErrorCodeEnum.API_ERROR_208029);
            }
            Long customerId = data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr());
            String corpid = paymentSheetEntityExt.getCorpid();
            PaymentBalanceEntity paymentBalanceEntity = paymentBalanceModel.getByCustomerId(customerId, corpid);
            if(paymentBalanceEntity == null){
                if(advancePaymentBalance < 0 ){
                    throw  new XbbException(PaymentErrorCodeEnum.API_ERROR_208041);
                }
                paymentBalanceEntity = new PaymentBalanceEntity();
                paymentBalanceEntity.setCorpid(corpid);
                String key = String.format(SymbolConstant.UNDERLINE_PLACE, RedisPrefixConstant.PAYMENT_BALANCE_FORM, distributorMark);
                String value = paasRedisHelper.getValue(key, corpid);
                PaasFormEntityExt paasFormEntity;
                if(StringUtil.isNotEmpty(value)){
                    paasFormEntity = JsonHelperUtil.parseObject(value,PaasFormEntityExt.class);
                }else{
                     paasFormEntity  = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), corpid, distributorMark,"id,app_id,menu_id,distributor_mark");
                    paasRedisHelper.setValue(key, corpid, paasFormEntity, RedisConstant.TINY_DURATION);
                }
                paymentBalanceEntity.setAppId(paasFormEntity.getAppId());
                paymentBalanceEntity.setMenuId(paasFormEntity.getMenuId());
                paymentBalanceEntity.setFormId(paasFormEntity.getId());
                //以下字段来自回款单
                paymentBalanceEntity.setOwnerId(paymentSheetEntityExt.getOwnerId());
                paymentBalanceEntity.setDepartmentId(paymentSheetEntityExt.getDepartmentId());
                paymentBalanceEntity.setCustomerId(customerId);
                paymentBalanceEntity.setAdvancePaymentBalance(advancePaymentBalance);
                paymentBalanceEntity.setCreatorId(paymentSheetEntityExt.getCreatorId());
                long now = DateUtil.getNow();
                paymentBalanceEntity.setAddTime(now);
                paymentBalanceEntity.setUpdateTime(now);
                paymentBalanceEntity.setDel(0);
                Integer insert = paymentBalanceModel.insert(paymentBalanceEntity);
                if(Objects.equals(PaymentBalanceInsertConstant.INSERT,insert)){
                    //插入团队
                    saasPaymentSheetHelper.insertBalanceUser(customerId, corpid, paymentBalanceEntity);
                }
                //更新团队  更新不在此处处理  在客户团队更新处处理
            }else{
                if(Arith.add(advancePaymentBalance,paymentBalanceEntity.getAdvancePaymentBalance()) < 0 ){
                    throw  new XbbException(PaymentErrorCodeEnum.API_ERROR_208041);
                }
                paymentBalanceEntity.setAdvancePaymentBalance(advancePaymentBalance);
                //删除后的重建
                boolean updateDel = false;
                if(Objects.equals(paymentBalanceEntity.getDel(),1)){
                    paymentBalanceEntity.setDel(0);
                    updateDel = true;
                }
                paymentBalanceModel.update(paymentBalanceEntity,updateDel);
                //删除后的重建
                if(updateDel){
                    saasPaymentSheetHelper.insertBalanceUser(customerId, corpid, paymentBalanceEntity);
                }
                //更新团队  更新不在此处处理  在客户团队更新处处理
            }
        } catch (XbbException e) {
            throw  e;
        }catch (Exception e){
            LOG.error(PaymentErrorCodeEnum.API_ERROR_208044.getMsg() ,e);
            throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208044);
        }
    }



    @Override
    public PrePaymentBalanceListVO prepaymentBalanceList(FormDataListDTO formDataListDTO) throws XbbException {
        PrePaymentBalanceListPojo prePaymentBalanceListPojo =  prePayMentBalanceCommonList(formDataListDTO);
        //
        PrePaymentBalanceListVO prePaymentBalanceListVO = new PrePaymentBalanceListVO();
        PageHelper pageHelper = new PageHelper(formDataListDTO.getPage(), formDataListDTO.getPageSize());
        pageHelper.setRowsCount( prePaymentBalanceListPojo.getRowsCount());
        prePaymentBalanceListVO.setPaasFormDataESList(prePaymentBalanceListPojo.getResultList());
        prePaymentBalanceListVO.setPageHelper(pageHelper);
        prePaymentBalanceListVO.setBusinessType(formDataListDTO.getBusinessType());

        prePaymentBalanceListVO.setForm(prePaymentBalanceListPojo.getForm());
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(prePaymentBalanceListPojo.getExplainList());
        handlerExplainDTO.setPaasFormEntityExt(prePaymentBalanceListPojo.getForm());
        HandlerExplainVO handlerExplainVO = formDataListFormExplainHandleName.handleExplain(handlerExplainDTO);
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        prePaymentBalanceListVO.setHeadList(handlerExplainVO.getHeadList());
        prePaymentBalanceListVO.setExplainMap(formDataListDTO.getExplainMap());
        // 设置列表页操作栏
        saasListHelp.setOption(prePaymentBalanceListVO, formDataListDTO);
        prePaymentBalanceListVO.setTopPermissions(prePaymentBalanceListPojo.getTopPermissions());
        prePaymentBalanceListVO.setBottomPermissions(prePaymentBalanceListPojo.getBottomPermissions());
        prePaymentBalanceListVO.setSortValue(prePaymentBalanceListPojo.getSortValue());
        return prePaymentBalanceListVO;
    }

    @Override
    public ListAppVO prepaymentBalanceAppList(FormDataListDTO formDataListDTO) throws XbbException {
        PrePaymentBalanceListPojo prePaymentBalanceListPojo = prePayMentBalanceCommonList(formDataListDTO);
        ListAppVO listAppVO = new ListAppVO();
        Integer rowsCount = prePaymentBalanceListPojo.getRowsCount();
        listAppVO.setTotalCount(rowsCount);
        listAppVO.setBusinessType(formDataListDTO.getBusinessType());
        List<AppListPojo> list = new ArrayList<>();
        if (rowsCount != null && rowsCount != 0) {
            List<PaymentBalanceEntity> resultList = prePaymentBalanceListPojo.getResultList();
            PaasFormEntityExt form = prePaymentBalanceListPojo.getForm();
            JSONArray summaryArray = form.getSummaryList();
            JSONArray titleArray = JSONArray.parseArray(form.getCustomTitle());
            for (PaymentBalanceEntity paymentBalanceEntity : resultList) {
                JSONObject data = paymentBalanceEntity.getData();
                //摘要
                List<SummaryDataPoJo> summaryList = new ArrayList<>();
                if(CollectionsUtil.isNotEmpty(summaryArray)){
                    for (int i = 0; i < summaryArray.size(); i++) {
                        SummaryDataPoJo summaryDataPoJo   = summaryArray.getJSONObject(i).toJavaObject(SummaryDataPoJo.class);
                        Object value = data.get(summaryDataPoJo.getAttr());
                        if(value != null){
                            summaryDataPoJo.setValue(Arrays.asList(value.toString()));
                            summaryList.add(summaryDataPoJo);
                        }
                    }
                }
                //标题
                List<FormTitlePoJo> titleList = new ArrayList<>();
                if(CollectionsUtil.isNotEmpty(titleArray)){
                    for (int i = 0; i < titleArray.size(); i++) {
                        FormTitlePoJoSub formTitlePoJoSub =  titleArray.getJSONObject(i).toJavaObject(FormTitlePoJoSub.class);
                        JSONArray jSONArray  = data.getJSONArray(formTitlePoJoSub.getAttr());
                        if(CollectionsUtil.isNotEmpty(jSONArray)){
                            //应该按照类型解析  (关联业务单选)
                            LinkBusinessSinglePojo  linkBusinessSinglePojo  = jSONArray.getJSONObject(0).toJavaObject(LinkBusinessSinglePojo.class);
                            Long id = linkBusinessSinglePojo.getId();
                            String value = linkBusinessSinglePojo.getName();
                            if(id != null && value != null){
                                formTitlePoJoSub.setId(id);
                                formTitlePoJoSub.setValue(Collections.singletonList(value));
                                titleList.add(formTitlePoJoSub);
                            }
                        }
                    }
                }
                //others
                JSONObject others = new JSONObject();
                String advancePaymentBalance = data.getString(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr());
                if(StringUtil.isNotEmpty(advancePaymentBalance)){
                    advancePaymentBalance +=  UnitEnum.MONEY.getName();
                }
                others.put("amount", advancePaymentBalance);
                JSONObject superScript = new JSONObject();
                List<SummaryDataPoJo> lablesList = new ArrayList<>();
                list.add(new AppListPojo(paymentBalanceEntity.getId(), titleList, summaryList, superScript, lablesList, others, paymentBalanceEntity.getAppId(), paymentBalanceEntity.getMenuId(), paymentBalanceEntity.getFormId()));
            }
        } else {
            rowsCount = 0;
        }
        listAppVO.setList(list);
        listAppVO.setTotalCount(rowsCount);
        //权限
        Boolean addPermission = false;
        List<ButtonPojo> buttonPojoList = prePaymentBalanceListPojo.getTopPermissions();
        if (Objects.nonNull(buttonPojoList) && !buttonPojoList.isEmpty()) {
            for (ButtonPojo buttonPojo : buttonPojoList) {
                if (Objects.nonNull(buttonPojo) && Objects.equals(buttonPojo.getAttr(), SaasButtonEnum.ADD.getAttr())) {
                    addPermission = true;
                }
            }
        }
        listAppVO.setAddPermission(addPermission);
        return listAppVO;
    }

    @Override
    public MobileFormCommonDetailVO getMoblieDetail(FormDataGetDTO formDataGetDTO) throws XbbException {
        Integer distributorMark = formDataGetDTO.getDistributorMark();
        boolean distributorMarkFlag = Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode());
        MobileFormCommonDetailVO   mobileFormCommonDetailVO = new MobileFormCommonDetailVO();
        // 查看权限校验
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
        BeanUtil.copyProperties(formDataGetDTO, verifyViewPermissionDTO);
        ProPermissionHelp.verifyQueryPermission(verifyViewPermissionDTO);
        String corpid = formDataGetDTO.getCorpid();
        PaymentBalanceEntity paymentBalanceEntity = paymentBalanceModel.getById(formDataGetDTO.getDataId(), corpid);
        if (paymentBalanceEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //
        Long formId = paymentBalanceEntity.getFormId();
        //验证表单和解释
        PaasFormEntityExt paasFormEntity = varifyFormAndExplain(corpid, formId);
        //设置客户名称
        Long customerId = paymentBalanceEntity.getCustomerId();
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId, corpid);
        JSONObject data = (JSONObject) JSONObject.toJSON(paymentBalanceEntity);
        String customerName = null;
        if(customerEntity != null){
            customerName = customerEntity.getData().getString(CustomerManagementEnum.NAME.getAttr());
            data.remove("data");
            data.remove("sourceData");
            data.put(PaymentBalanceEnum.CUSTOMER_NAME.getAttr(),customerName);
        }
        mobileFormCommonDetailVO.setData(data);
        mobileFormCommonDetailVO.setPaasFormEntity(paasFormEntity);
        //titleLis标题
        FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
        formTitlePoJo.setAttr(PaymentBalanceEnum.CUSTOMER_ID.getAttr());
        String titleCustomerName;
        if (distributorMarkFlag) {
            titleCustomerName = PaymentBalanceDistributorEnum.CUSTOMER_ID.getAttrName();
        } else {
            titleCustomerName = PaymentBalanceEnum.CUSTOMER_ID.getAttrName();
        }
        formTitlePoJo.setAttrName(titleCustomerName);
        String value = data.getString(PaymentBalanceEnum.CUSTOMER_NAME.getAttr());
        if(value == null){
            value = "";
        }
        formTitlePoJo.setValue(Arrays.asList(value));
        mobileFormCommonDetailVO.setTitleList(Arrays.asList(formTitlePoJo));
        //摘要
        List<SummaryDataPoJo> summaryList = new ArrayList<>();
        SummaryExtraDataPoJo summaryExtraDataPoJo = new SummaryExtraDataPoJo(customerId,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        JSONObject summaryExtraDataJsonObject = (JSONObject) JSON.toJSON(summaryExtraDataPoJo);
        SummaryDataPoJo  customerSummaryDataPoJo = new SummaryDataPoJo(PaymentBalanceEnum.CUSTOMER_ID.getAttr(),titleCustomerName,PaymentBalanceEnum.CUSTOMER_ID.getFieldType(),Arrays.asList(data.getString(PaymentBalanceEnum.CUSTOMER_NAME.getAttr())),summaryExtraDataJsonObject);

        summaryList.add(customerSummaryDataPoJo);
        mobileFormCommonDetailVO.setSummaryList(summaryList);
        //右侧
        MobileDetailSpecialInfoPojo specialInfoPojo = new MobileDetailSpecialInfoPojo();
        List<MobileDetailScriptPojo> script = new ArrayList<>();
        MobileDetailScriptPojo pojo = new MobileDetailScriptPojo();
        //精度
        Integer accuracy =  getAccuracy(corpid, distributorMark);
        Double advancePaymentBalance = paymentBalanceEntity.getAdvancePaymentBalance();
        Object moneyStr =  AttrDecimalPrecisionHelper.parseThousandth(advancePaymentBalance,accuracy);
        pojo.setMoneyScript(moneyStr + UnitEnum.MONEY.getName());
        script.add(pojo);
        specialInfoPojo.setScript(script);
        mobileFormCommonDetailVO.setRightSpecialInfo(specialInfoPojo);
        //tab
        UserVO loginUser = formDataGetDTO.getLoginUser();
        List<DetailTabPojo> tabList = getDetailTabPojos(distributorMarkFlag, XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(),loginUser,PlatFormEnum.DINGTALK,corpid,formId);
        mobileFormCommonDetailVO.setTabList(tabList);
        //权限
        //只有当预收款余额>0，切待核销合同个数大于0才可以核销
        Map<Long, Integer> contractCountMap = getContractCountByCustomer(corpid, Arrays.asList(customerId));
        Integer contractCount = contractCountMap.get(customerId);
        boolean contractCountB = contractCount != null && contractCount > 0;
        boolean advanceB = advancePaymentBalance != null && advancePaymentBalance > 0;
        List<TopPermissionsPoJo> topPermissions = new ArrayList<>();
        if(advanceB ){
            Set<String> permSet = loginUser.getPermSet();
            if(contractCountB ){
                if (permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_ADD.getAlias()) && !Objects.equals(ProPermissionAliasEnum.PAYMENT_SHEET_ADD.getAlias(), StringConstant.POSITIVE_NUMBER)) {
                    TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
                    MobileDetailBottomOperationEnum mobileDetailBottomOperationEnum = MobileDetailBottomOperationEnum.PREPAYMENT_BALANCE_UPDATE;
                    topPermissionsPoJo.setAttr(mobileDetailBottomOperationEnum.getAttr());
                    topPermissionsPoJo.setBtnType(mobileDetailBottomOperationEnum.getBtnType());
                    topPermissionsPoJo.setBusinessType(mobileDetailBottomOperationEnum.getBusinessType());
                    topPermissionsPoJo.setValue(mobileDetailBottomOperationEnum.getValue());
                    topPermissionsPoJo.setDistributorMark(distributorMark);
                    topPermissions.add(topPermissionsPoJo);
                }
            }
            if (permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_RED.getAlias()) && !Objects.equals(ProPermissionAliasEnum.PAYMENT_SHEET_RED.getAlias(), StringConstant.POSITIVE_NUMBER)) {
                TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
                MobileDetailBottomOperationEnum mobileDetailBottomOperationEnum = MobileDetailBottomOperationEnum.PREPAYMENT_BALANCE_RED;
                topPermissionsPoJo.setAttr(mobileDetailBottomOperationEnum.getAttr());
                topPermissionsPoJo.setBtnType(mobileDetailBottomOperationEnum.getBtnType());
                topPermissionsPoJo.setBusinessType(mobileDetailBottomOperationEnum.getBusinessType());
                topPermissionsPoJo.setValue(mobileDetailBottomOperationEnum.getValue());
                topPermissionsPoJo.setDistributorMark(distributorMark);
                topPermissions.add(topPermissionsPoJo);
            }
        }
        //非经销商类型才有删除按钮
        MobileDetailBottomOperationEnum mobileDetailBottomOperationEnum = MobileDetailBottomOperationEnum.PREPAYMENT_BALANCE_DEL;
        TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo.Builder().attr(mobileDetailBottomOperationEnum.getAttr())
                .btnType(mobileDetailBottomOperationEnum.getBtnType()).businessType(mobileDetailBottomOperationEnum.getBusinessType())
                .value(mobileDetailBottomOperationEnum.getValue()).build();
        topPermissions.add(topPermissionsPoJo);
        mobileFormCommonDetailVO.setTopPermissions(topPermissions);

        //处理bottomBlockInfo
        JSONArray bottomBlockInfo = new JSONArray();
        bottomBlockInfo.add(new MobileDetailDirectBlockPojo(customerId, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), customerName));
        mobileFormCommonDetailVO.setBottomBlockInfo(bottomBlockInfo);

        return mobileFormCommonDetailVO;
    }

    @Override
    public FormDataDetailVO getWebDetail(FormDataDetailDTO formDataDetailDTO) throws XbbException {
        FormDataDetailVO formDataDetailVO = new FormDataDetailVO();
        FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
        BeanUtil.copyProperties(formDataDetailDTO,formDataGetDTO);
        String corpid = formDataGetDTO.getCorpid();
        PaymentBalanceEntity paymentBalanceEntity = paymentBalanceModel.getById(formDataGetDTO.getDataId(), corpid);
        if (paymentBalanceEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //
        Long formId = paymentBalanceEntity.getFormId();
        //验证表单和解释
        PaasFormEntityExt paasFormEntity = varifyFormAndExplain(corpid, formId);
        Integer distributorMark = paasFormEntity.getDistributorMark();
        boolean distributorMarkFlag = Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode());
        formDataDetailDTO.setDistributorMark(distributorMark);
        formDataGetDTO.setDistributorMark(distributorMark);
        //设置客户名称
        Long customerId = paymentBalanceEntity.getCustomerId();
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId, corpid);
        String customerName = "";
        if(customerEntity != null){
             customerName = customerEntity.getData().getString(CustomerManagementEnum.NAME.getAttr());
        }
        formDataDetailVO.setTab(getDetailTabPojos(distributorMarkFlag, XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(),formDataDetailDTO.getLoginUser(),PlatFormEnum.WEB,corpid,formId));
        PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
        BeanUtil.copyProperties(paasFormEntity,paasFormEntityExt);
        formDataDetailVO.setPaasFormEntityExt(paasFormEntityExt);
        //副标题
         JSONArray secondTitle = new JSONArray();
        String titleCustomerName;
        if (distributorMarkFlag) {
            titleCustomerName = PaymentBalanceDistributorEnum.CUSTOMER_ID.getAttrName();
        } else {
            titleCustomerName = PaymentBalanceEnum.CUSTOMER_ID.getAttrName();
        }
        List<LinkBusinessSinglePojo> customerLink = fundHelp.getLinkBusinessSinglePojos(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), customerId, customerName, distributorMark);
        secondTitle.add( ExplainUtil.getSecondTitleObj(false, titleCustomerName, customerLink,"though"));
        //金额的处理
        //精度
        Integer accuracy =  getAccuracy(corpid, distributorMark);
        Double advancePaymentBalance = paymentBalanceEntity.getAdvancePaymentBalance();
        Object moneyStr =  AttrDecimalPrecisionHelper.parseThousandth(advancePaymentBalance,accuracy);
        secondTitle.add( ExplainUtil.getSecondTitleObj(false, PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttrName(), moneyStr + UnitEnum.MONEY.getName()));
        //头部信息（包含操作）
        DataDetailPojo dataDetailPojo = new DataDetailPojo();
        //标题
        DetailTitlePojo title = new DetailTitlePojo();
        title.setName(customerName);
        dataDetailPojo.setTitle(title);
        dataDetailPojo.setSecondTitle(secondTitle);
        //
        List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
        //只有当预收款余额>0，切待核销合同个数大于0才可以核销
        Map<Long, Integer> contractCountMap = getContractCountByCustomer(corpid, Arrays.asList(customerId));
        Integer contractCount = contractCountMap.get(customerId);
        boolean contractCountB = contractCount != null && contractCount > 0;
        boolean advanceB = advancePaymentBalance != null && advancePaymentBalance > 0;
        if(advanceB ){
            UserVO loginUser = formDataGetDTO.getLoginUser();
            Set<String> permSet = loginUser.getPermSet();
            if (contractCountB) {
                //核销
                if (permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_ADD.getAlias()) && !Objects.equals(ProPermissionAliasEnum.PAYMENT_SHEET_ADD.getAlias(), StringConstant.POSITIVE_NUMBER)) {
                    setWorkFlowPojo(distributorMark, workFlowPojoList, BusinessDetailButtonEnum.PREPAYMENT_BALANCE_UPDATE);
                }
            }
            //红冲退款
            if (permSet.contains(ProPermissionAliasEnum.PAYMENT_SHEET_RED.getAlias()) && !Objects.equals(ProPermissionAliasEnum.PAYMENT_SHEET_RED.getAlias(), StringConstant.POSITIVE_NUMBER)) {
                setWorkFlowPojo(distributorMark, workFlowPojoList, BusinessDetailButtonEnum.PREPAYMENT_BALANCE_RED);
            }
        }
        //增加一个校正按钮
        ManagementButtomEnum prepaymentBalanceFix = ManagementButtomEnum.PREPAYMENT_BALANCE_FIX;
        WorkFlowPojo workFlowPojo = new WorkFlowPojo();
        workFlowPojo.setAttr(prepaymentBalanceFix.getAttr());
        workFlowPojo.setBtnType(prepaymentBalanceFix.getBtuType());
        workFlowPojo.setBusinessType(prepaymentBalanceFix.getBusinessType());
        workFlowPojo.setValue(prepaymentBalanceFix.getValue());
        workFlowPojoList.add(workFlowPojo);
        dataDetailPojo.setWorkFlow(workFlowPojoList);
        //按钮
        if (!distributorMarkFlag) {
            //非经销商类型才有删除按钮
            ButtonPojo buttonPojo = new ButtonPojo();
            SaasButtonEnum saasButtonEnum = BusinessDetailButtonEnum.PREPAYMENT_BALANCE_DEL.getAnEnum();
            BeanUtil.copyProperties(saasButtonEnum, buttonPojo);
            List<ButtonPojo> buttonPojoList = new ArrayList<>();
            buttonPojoList.add(buttonPojo);
            dataDetailPojo.setButton(buttonPojoList);
        }
        dataDetailPojo.setTags(new JSONArray());
        dataDetailPojo.setTabSortPermission(true);
        dataDetailPojo.setDial(new ArrayList<>());
        formDataDetailVO.setHead(dataDetailPojo);

        return formDataDetailVO;
    }

    @Override
    public PaymentSheetFromBalanceListVO paymentSheetFromBalanceList(PaymentSheetFromBalanceDTO paymentSheetFromBalanceDTO) throws XbbException {
        String corpid = paymentSheetFromBalanceDTO.getCorpid();
        PaasFormEntityExt paasFormBalance = paasFormModel.getByKey(paymentSheetFromBalanceDTO.getFormId(), corpid);
        if(paasFormBalance == null){
            throw  new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        Integer distributorMark = paasFormBalance.getDistributorMark();
        PaasFormEntityExt paasForm = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid, distributorMark, null);
        if(paasForm == null){
            throw  new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(paasForm.getId(), corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        paymentSheetFromBalanceDTO.setDistributorMark(distributorMark);
        paymentSheetFromBalanceDTO.setBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        paymentSheetFromBalanceDTO.setSubBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        paymentSheetFromBalanceDTO.setAppId(paasForm.getAppId());
        paymentSheetFromBalanceDTO.setFormId(paasForm.getId());
        paymentSheetFromBalanceDTO.setPlatform(PlatFormEnum.WEB.getValue());
        //设置explains
        formDataListSearchHelp.handlExplains(paymentSheetFromBalanceDTO,paasForm);
        List<ConditionsEntityExt> conditionList = paymentSheetFromBalanceDTO.getConditions();
        conditionList.add(new ConditionsEntityExt(PaymentSheetEnum.CUSTOMER_ID.getAttr(), "", FieldTypeEnum.LINK_BUSINESS_SINGLE.getType(), ConditionEnum.EQUAL.getSymbol(), Arrays.asList(paymentSheetFromBalanceDTO.getCustomerId())));
        //预收款、预收款核销、红冲预收款余额、红冲预收款核销(退到余额)
        List<Object> codeList4Balance = PaymentSheetTypeEnum.getCodeList4Balance();
        conditionList.add(new ConditionsEntityExt(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), "", FieldTypeEnum.TEXT.getType(), ConditionEnum.IN.getSymbol(), codeList4Balance));
        //过滤审批中的数据（后面有统一的处理）
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(paymentSheetFromBalanceDTO,formDataListDTO);
        List<String> fieldList = Arrays.asList(PaymentSheetEnum.PAYMENT_TIME.getAttr(),  PaymentSheetEnum.AMOUNT.getAttr(), PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(), PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), PaymentSheetEnum.SHEET_NO.getAttr());
        formDataListDTO.setFieldList(fieldList);
        //排序  按照添加时间正序  编辑金额不允许修改  格式 {field: "addTime", sort: "asc"}
        Map<String, String> sortMap = new HashMap<>(2);
        sortMap.put("field",PaymentSheetEnum.ADD_TIME.getAttr());
        sortMap.put("sort","asc");
        formDataListDTO.setSortMap(sortMap);
        FormDataListDTO newFormDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(paymentSheetFromBalanceDTO,newFormDataListDTO);
        List<ConditionsEntityExt> conditions = (List<ConditionsEntityExt>) CloneUtil.deepClone(conditionList);
        newFormDataListDTO.setConditions(conditions);
        PaasFormDataEsListVO formDataListVO = saasListService.paymentSheetList(formDataListDTO);
        List<FieldAttrEntity> headList = formDataListVO.getHeadList();
        List<FieldAttrEntity> newHeadList = new ArrayList<>();
        for (FieldAttrEntity fieldAttrEntity : headList) {
            if(fieldList.contains(fieldAttrEntity.getAttr())){
                newHeadList.add(fieldAttrEntity);
            }
        }
        //添加预收款余额字段
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        fieldAttrEntity.setAttr(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr());
        fieldAttrEntity.setAttrName(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttrName());
        fieldAttrEntity.setFieldType(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getFieldType());
        newHeadList.add(fieldAttrEntity);
        //预收款余额
        double  advancePaymentBalance = 0;
        double  amount= 0;
        double  writeOffAmount= 0;
        //从第二页开始要计算前面的预收款余额
        Integer page = paymentSheetFromBalanceDTO.getPage();
        if(page != null && page >1){
            List<PaasFormDataEntityExt> paasFormDataESList = formDataListVO.getPaasFormDataESList();
            if(CollectionsUtil.isNotEmpty(paasFormDataESList)){
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                //计算本页之前的数据
                PaasFormDataEntityExt paasFormDataEntityExt = paasFormDataESList.get(0);
                boolQueryBuilder.filter(rangeQuery(FieldTypeEnum.DATAID.getAlias()).lt( paasFormDataEntityExt.getDataId()));
                //只要无子和父的
                boolQueryBuilder.filter(termsQuery(BasicConstant.ALONE, SheetAloneEnum.getNotChildCodeList()));
                boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
                //预收款流水
                NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET;
                paasFormDataEsModel.getSearchRequest(newFormDataListDTO, indexTypeEnum, sourceBuilder, boolQueryBuilder);
                nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
                NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
                List<AggSumDTO> sumList = new ArrayList<>();
                // 统计字段
                //回款金额
                AggSumDTO amountAggSumDTO = getAggSumDTO(PaymentSheetEnum.AMOUNT);
                sumList.add(amountAggSumDTO);
                AggSumDTO writeOffAmountAggSumDTO = getAggSumDTO(PaymentSheetEnum.WRITE_OFF_AMOUNT);
                //核销金额
                sumList.add(writeOffAmountAggSumDTO);
                List<AggSumVO> aggSumList = esHelper.aggSumByField(indexTypeEnum.getIndex(), indexTypeEnum.getType(), sumList, searchQuery);
                for (AggSumVO aggSumVO : aggSumList) {
                    Double value = Double.valueOf(aggSumVO.getValue().toString());
                    if(Objects.equals(PaymentSheetEnum.AMOUNT.getAttr(), aggSumVO.getAttr())){
                        amount = Arith.add(amount, value);
                        advancePaymentBalance = Arith.add(advancePaymentBalance, value);
                    }else if(Objects.equals(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(), aggSumVO.getAttr())){
                        writeOffAmount = Arith.add(writeOffAmount, value);
                        advancePaymentBalance = Arith.sub(advancePaymentBalance, value);
                    }
                }
            }
        }
        List<PaasFormDataEntityExt> paasFormDataESList = formDataListVO.getPaasFormDataESList();
        Integer accuracy = formDataListVO.getExplainMap().get((PaymentSheetEnum.AMOUNT.getAttr())).getAccuracy();
        if(CollectionsUtil.isNotEmpty(paasFormDataESList)){
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
                JSONObject data  = paasFormDataEntityExt.getData();
                JSONObject sourceData  = paasFormDataEntityExt.getSourceData();
                //原值
                advancePaymentBalance = Arith.add(advancePaymentBalance,getDouble(sourceData.getString(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr())) );
                //回款金额
                double innerAmount = getDouble(sourceData.getString(PaymentSheetEnum.AMOUNT.getAttr()));
                amount = Arith.add(amount, innerAmount);
                advancePaymentBalance = Arith.add(advancePaymentBalance, innerAmount);
                //核销金额
                double innerWriteOffAmount = getDouble(sourceData.getString(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr()));
                writeOffAmount = Arith.add(writeOffAmount, innerWriteOffAmount);
                advancePaymentBalance = Arith.sub(advancePaymentBalance, innerWriteOffAmount);
                data.put(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr(),AttrDecimalPrecisionHelper.parseThousandth(advancePaymentBalance,accuracy));
            }
            formDataListVO.setPaasFormDataESList(paasFormDataESList);
        }
        formDataListVO.setHeadList(newHeadList);
        PaymentSheetFromBalanceListVO  paymentSheetFromBalanceListVO = new PaymentSheetFromBalanceListVO();
        BeanUtil.copyProperties(formDataListVO,paymentSheetFromBalanceListVO);
        Map<String, Object> summary = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        summary.put(PaymentSheetEnum.AMOUNT.getAttr(),AttrDecimalPrecisionHelper.parseThousandth(amount,accuracy));
        summary.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),AttrDecimalPrecisionHelper.parseThousandth(writeOffAmount,accuracy));
//        summary.put(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr(),attrDecimalPrecisionHelper.parseThousandth(advancePaymentBalance,accuracy));
        paymentSheetFromBalanceListVO.setSummary(summary);
        return paymentSheetFromBalanceListVO;
    }

    @Override
    public PaymentSheetFromBalanceVO getByCustomerId(PaymentSheetFromBalanceDTO paymentSheetFromBalanceDTO) throws XbbException {
        Long customerId = paymentSheetFromBalanceDTO.getCustomerId();
        PaymentBalanceEntity entity = paymentBalanceModel.getByCustomerId(customerId, paymentSheetFromBalanceDTO.getCorpid());
        PaymentSheetFromBalanceVO paymentSheetFromBalanceVO = new PaymentSheetFromBalanceVO();
        Double advancePaymentBalance = 0D;
        if (entity != null) {
            advancePaymentBalance = entity.getAdvancePaymentBalance();
        }
        paymentSheetFromBalanceVO.setAdvancePaymentBalance(advancePaymentBalance);
        return paymentSheetFromBalanceVO;
    }

    private double getDouble(String s){
        if (s == null) {
            return 0D;
        }
        return Double.valueOf(s);
    }
    /**
     * 设置
     * @param amount
     * @return
     */
    private AggSumDTO getAggSumDTO(PaymentSheetEnum amount) {
        AggSumDTO aggSumDTO = new AggSumDTO();
        aggSumDTO.setAttr(amount.getAttr());
        aggSumDTO.setName(amount.getAttrName());
        aggSumDTO.setField("data."+amount.getAttr());
        FieldAttrEntity amountFieldAttrEntity = new FieldAttrEntity();
        amountFieldAttrEntity.setAttr(amount.getAttr());
        amountFieldAttrEntity.setAttrName(amount.getAttrName());
        amountFieldAttrEntity.setFieldType(amount.getFieldType());
        aggSumDTO.setFieldAttrEntity(amountFieldAttrEntity);
        return aggSumDTO;
    }

    private void setWorkFlowPojo(Integer distributorMark, List<WorkFlowPojo> workFlowPojoList, BusinessDetailButtonEnum businessDetailButtonEnum) {
        WorkFlowPojo workFlowPojo = new WorkFlowPojo();
        workFlowPojo.setAttr(businessDetailButtonEnum.getAnEnum().getAttr());
        workFlowPojo.setBtnType(businessDetailButtonEnum.getAnEnum().getAttr());
        workFlowPojo.setBusinessType(businessDetailButtonEnum.getLinkBusinessType());
        workFlowPojo.setValue(businessDetailButtonEnum.getAnEnum().getValue());
        workFlowPojo.setDistributorMark(distributorMark);
        workFlowPojoList.add(workFlowPojo);
    }

    private List<DetailTabPojo> getDetailTabPojos(boolean distributorMarkFlag, Integer businessType, UserVO userVO,PlatFormEnum platFormEnum,String corpid,Long formId) {
        List<BusinessDetailTabEnum> tabEnumList;
        if (Objects.equals(platFormEnum, PlatFormEnum.WEB)) {
            tabEnumList = BusinessDetailTabEnum.getByBusinessTypeAndPermission(businessType, userVO.getPermSet());
        } else {
            tabEnumList = BusinessDetailTabEnum.getByBusinessTypeAndPermissionForDingtalk(businessType, userVO.getPermSet());
        }
        List<DetailTabPojo> tabList = new ArrayList<>();
        for (BusinessDetailTabEnum tabEnum : tabEnumList) {
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(tabEnum.getAnEnum(), detailTabPojo);
            detailTabPojo.setAttr(detailTabPojo.getKey());
            if (distributorMarkFlag && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_VERIFY)) {
                detailTabPojo.setName(I18nMessageUtil.getMessage(I18nStringConstant.ORDER_VERIFY));
            }
            tabList.add(detailTabPojo);
        }
        tabList = proDetailHandlerHelp.handleDetailTabSort(userVO.getUserId(), corpid, formId, businessType, tabList);
        return tabList;
    }

    /**
     * 验证表单和解释
     * @param corpid
     * @param formId
     * @return
     * @throws XbbException
     */
    private PaasFormEntityExt varifyFormAndExplain(String corpid, Long formId) throws XbbException {
        PaasFormEntityExt paasFormEntity = paasFormModel.getByKey(formId, corpid);
        if (paasFormEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        return paasFormEntity;
    }


    /**
     * web和app通用列表信息
     * @param formDataListDTO
     * @return
     * @throws XbbException
     */
    private PrePaymentBalanceListPojo prePayMentBalanceCommonList(FormDataListDTO formDataListDTO) throws XbbException {
        if (!Objects.equals(formDataListDTO.getBusinessType(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode())){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        String corpid =  formDataListDTO.getCorpid();
        List<ConditionsEntityExt> conditionList = formDataListDTO.getConditions();
        if(CollectionsUtil.isNotEmpty(conditionList)){
            for (ConditionsEntityExt conditionsEntityExt : conditionList) {
                if(Objects.equals(FieldTypeEnum.DATAID.getAlias(),conditionsEntityExt.getAttr())){
                    conditionsEntityExt.setAttr(FieldTypeEnum.DATAID.getDescription());
                    break;
                }
            }
        }
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(formDataListDTO.getLoginUser(),userEntity);
        saasListDataPermissionHelp.listDataPermission(conditionList,formDataListDTO.getLoginUser(),XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), formDataListDTO.getSubBusinessType());
        // app端范围筛选
        saasListDataPermissionHelp.dingtalkRangeScreen(conditionList, userEntity, XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), formDataListDTO.getSubBusinessType(), formDataListDTO.getPlatform());
        formDataListDTO.setConditions(conditionList);
        //分组条件
        List<ConditionsEntityExt> groupConditionsList = new ArrayList<>();
        formDataListDTO.getConditions().addAll(groupConditionsList);
        //表单获取
        PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
        if (Objects.nonNull(form)) {
            formDataListDTO.setDistributorMark(form.getDistributorMark());
        }
        //解释获取以及处理
        HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlExplains(formDataListDTO,form);
        List<FieldAttrEntity> explainList = handleExplainPojo.getExplainList();
        //解释获取以及处理
//        Map<String,FieldAttrEntity> secondaryExplainMap = formDataListSearchHelp.secondaryExplains(formDataListDTO);
        //默认排序 字段显示
        formDataListSearchHelp.setListColumn(formDataListDTO);
        // 获取paas的本人及其下属的数据
        formDataListDTO.setConditions(formDataListSearchHelp.getPaasPermission(formDataListDTO));
        //模糊查询高级模式
        formDataListSearchHelp.nameLikeSupprtSet(formDataListDTO);
        //查询条件
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //nameLike的处理（右上角的搜索）
        String nameLike = formDataListDTO.getNameLike();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        if(StringUtil.isNotEmpty(nameLike)){
            IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
            BoolQueryBuilder customerBoolQueryBuilder = boolQuery();
            //解析查询条件
            customerBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            customerBoolQueryBuilder.filter(termQuery("del", 0));
            customerBoolQueryBuilder.should(matchPhraseQuery(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME), nameLike));
            customerBoolQueryBuilder.should(matchPhraseQuery(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.PHONE)+".text_2", nameLike));
            customerBoolQueryBuilder.minimumShouldMatch(EsNormalConstant.MINI_MUM_SHOULD_MATCH);
            customerBoolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
            SearchRequest customerSearchRequest = new SearchRequest(customerIndex.getIndex());
            SearchSourceBuilder customerSourceBuilder = new SearchSourceBuilder();
            List<String> fieldList = Arrays.asList("id");
            EsUtil.setFieldList(customerSourceBuilder, fieldList);
            //模糊关联查询最多1W
            PageRequest customerPageRequest =  EsUtil.setPage(customerSourceBuilder, 1,  SizeConstant.PAGE_SIZE);
            customerSourceBuilder.query(customerBoolQueryBuilder);
            customerSearchRequest.source(customerSourceBuilder);
            XbbAggregatedPage<CustomerEntityExt> customerEntityExts =  xbbElasticsearchRestTemplate.queryForPages(customerPageRequest, customerSearchRequest,CustomerEntityExt.class);
            if (customerEntityExts != null) {
                List<CustomerEntityExt> customerResultList  =  customerEntityExts.getContent();
                List<Long> customerIdList = new ArrayList<>(customerResultList.size());
                for (CustomerEntityExt customerEntityExt : customerResultList) {
                    customerIdList.add(customerEntityExt.getDataId());
                }
                boolQueryBuilder.filter(termsQuery(PaymentBalanceEnum.CUSTOMER_ID.getAttr(),customerIdList));
            }
        }
        SearchRequest searchRequest = paasFormDataEsModel.getSearchRequest(formDataListDTO, indexTypeEnum, sourceBuilder, boolQueryBuilder);
        //数据查询
        List<PaymentBalanceEntity> resultList;
        long num;
        PrePaymentBalanceListPojo prePaymentBalanceListPojo = new PrePaymentBalanceListPojo();
        if (Objects.equals(formDataListDTO.getFromExport(), 1)) {
            EsUtil.setPage(sourceBuilder, 1, PaasConstant.ES_MAX_PAGE_SIZE);
            resultList = xbbElasticsearchRestTemplate.getScrollListForExport(PaymentBalanceEntity.class, searchRequest);
            num = resultList.size();
        } else {
            //分页
            PageRequest pageRequest= EsUtil.setPage(sourceBuilder, formDataListDTO.getPage(), formDataListDTO.getPageSize());
            XbbAggregatedPage<PaymentBalanceEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest,PaymentBalanceEntity.class);
            if (esEntities == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            prePaymentBalanceListPojo.setSortValue(esEntities.getSortValue());
            resultList =  esEntities.getContent();
            num = esEntities.getTotalElements();
        }
        List<Long> customerIdList = new ArrayList<>(resultList.size());
        for (PaymentBalanceEntity paymentBalanceEntity : resultList) {
            paymentBalanceEntity.setDataId(paymentBalanceEntity.getId());
            JSONObject obj = (JSONObject) JSONObject.toJSON(paymentBalanceEntity);
            obj.remove("data");
            paymentBalanceEntity.setData(obj);
            paymentBalanceEntity.setSourceData(obj);
            customerIdList.add(paymentBalanceEntity.getCustomerId());
        }
        Map<Long,String> customerMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Integer> contractCountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(customerIdList)){
            //关联客户的渲染
            List<CustomerEntityExt> customerResultList= getCustomerEntityExts(formDataListDTO, corpid, customerIdList);
            if (customerResultList != null) {
                for (CustomerEntityExt customerEntityExt : customerResultList) {
                    customerMap.put(customerEntityExt.getId(),customerEntityExt.getData().getString(CustomerManagementEnum.NAME.getAttr()));
                }
            }
            //关联合同的渲染
            contractCountMap  = getContractCountByCustomer(corpid, customerIdList);
        }
        //精度
        Integer accuracy = 2;
        for (FieldAttrEntity balanceExplain : explainList) {
            if(Objects.equals(balanceExplain.getAttr(), PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr())){
                accuracy = balanceExplain.getAccuracy();
                break;
            }
        }
        for (PaymentBalanceEntity paymentBalanceEntity : resultList) {
            Long customerId = paymentBalanceEntity.getCustomerId();
            JSONObject obj = (JSONObject) JSONObject.toJSON(paymentBalanceEntity);
            obj.remove("data");
            obj.remove("sourceData");
            //把关联客户的解析放入
            String customerName = customerMap.get(customerId);
            List<LinkBusinessSinglePojo> customerLink = fundHelp.getLinkBusinessSinglePojos(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), customerId, customerName, formDataListDTO.getDistributorMark());
            obj.put(PaymentBalanceEnum.CUSTOMER_ID.getAttr(),customerLink);
            obj.put(PaymentBalanceEnum.CUSTOMER_NAME.getAttr(),customerName);
            Integer contractCount = contractCountMap.get(customerId);
            if(contractCount == null){
                contractCount = 0;
            }
            obj.put(PaymentBalanceEnum.CONTRACT_COUNT.getAttr(),contractCount);
            paymentBalanceEntity.setContractCount(contractCount);
            Double advancePaymentBalance = paymentBalanceEntity.getAdvancePaymentBalance();
            Object moneyStr =  AttrDecimalPrecisionHelper.parseThousandth(advancePaymentBalance,accuracy);
            obj.put(PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr(), moneyStr);
            paymentBalanceEntity.setData(obj);
        }

        //  ==================== 上部按钮权限和下部按钮权限 ====================

        PrePaymentBalanceListVO prePaymentBalanceListVO = new PrePaymentBalanceListVO();
        prePaymentBalanceListVO.setForm(form);
        formDataListSearchHelp.setButtons(formDataListDTO, prePaymentBalanceListVO);
        formDataListSearchHelp.explainFieldSort(formDataListDTO, explainList);
        prePaymentBalanceListPojo.setForm(form);
        prePaymentBalanceListPojo.setExplainList(explainList);
        prePaymentBalanceListPojo.setResultList(resultList);
        prePaymentBalanceListPojo.setRowsCount((int) num);
        prePaymentBalanceListPojo.setTopPermissions(prePaymentBalanceListVO.getTopPermissions());
        prePaymentBalanceListPojo.setBottomPermissions(prePaymentBalanceListVO.getBottomPermissions());
        return prePaymentBalanceListPojo;
    }

    /**
     * 获取关联的客户
     * @param formDataListDTO
     * @param corpid
     * @param customerIdList
     * @return
     * @throws XbbException
     */
    private List<CustomerEntityExt> getCustomerEntityExts(FormDataListDTO formDataListDTO, String corpid, List<Long> customerIdList) throws XbbException {
        IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        SearchRequest customerSearchRequest = new SearchRequest(customerIndex.getIndex());
        SearchSourceBuilder customerSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder customerBoolQueryBuilder = boolQuery();
        List<String> fieldList = Arrays.asList("id", CustomerManagementEnum.NAME.getAttr());
        EsUtil.setFieldList(customerSourceBuilder, fieldList);
        customerBoolQueryBuilder.filter(termsQuery("id", customerIdList));
        customerBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        customerBoolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
        //对应客户的数量和预收款条数相等，所以只查对应的大小即可
        PageRequest customerPageRequest =  EsUtil.setPage(customerSourceBuilder, 1, formDataListDTO.getPageSize());
        customerSourceBuilder.query(customerBoolQueryBuilder);
        customerSearchRequest.source(customerSourceBuilder);
        List<CustomerEntityExt> customerResultList ;
        if (Objects.equals(formDataListDTO.getFromExport(), 1)) {
            EsUtil.setPage(customerSourceBuilder, 1, SizeConstant.PAGE_SIZE);
            customerResultList = xbbElasticsearchRestTemplate.findScrollList(CustomerEntityExt.class,customerSearchRequest,SizeConstant.SCROLL_TIME_IN_MILLIS);
        }else{
            XbbAggregatedPage<CustomerEntityExt>  customerEntityExts =  xbbElasticsearchRestTemplate.queryForPages(customerPageRequest, customerSearchRequest,CustomerEntityExt.class);
            customerResultList =  customerEntityExts.getContent();
        }
        return customerResultList;
    }
//    private List<ContractEntityExt> getContractEntityExts(String corpid, List<Long> customerIdList) throws XbbException {
//        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
//        SearchRequest customerSearchRequest = new SearchRequest(indexTypeEnum.getIndex()).types(indexTypeEnum.getType());
//        SearchSourceBuilder customerSourceBuilder = new SearchSourceBuilder();
//        BoolQueryBuilder customerBoolQueryBuilder = boolQuery();
//        List<String> fieldList = Arrays.asList("id", ContractEnum.NAME.getAttr(), ContractEnum.LINK_CUSTOMER.getAttr());
//        EsUtil.setFieldList(customerSourceBuilder, fieldList);
//        customerBoolQueryBuilder.filter(termsQuery(ContractEnum.getEsAttr4Keyword(ContractEnum.LINK_CUSTOMER), customerIdList));
//        customerBoolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
//        //未收款金额>0
//        customerBoolQueryBuilder.filter(rangeQuery(ContractEnum.getAttrConnectData(ContractEnum.UN_FINISH_AMOUNT)).gt(0));
//        customerSourceBuilder.query(customerBoolQueryBuilder);
//        customerSearchRequest.source(customerSourceBuilder);
//        EsUtil.setPage(customerSourceBuilder, 1, SizeConstant.PAGE_SIZE);
//        List<ContractEntityExt> customerResultList = xbbElasticsearchRestTemplate.findScrollList(ContractEntityExt.class,customerSearchRequest,SizeConstant.SCROLL_TIME_IN_MILLIS);
//        return customerResultList;
//    }

    /**
     * 获取对应客户待核销的合同的个数map
     * @param corpid
     * @param customerIdList
     * @return
     * @throws XbbException
     */
    private Map<Long,Integer> getContractCountByCustomer(String corpid, List<Long> customerIdList) throws XbbException {
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
        BoolQueryBuilder customerBoolQueryBuilder = boolQuery();
        customerBoolQueryBuilder.filter(termsQuery(ContractEnum.getEsAttr4Keyword(ContractEnum.LINK_CUSTOMER), customerIdList));
        customerBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        customerBoolQueryBuilder.filter(termQuery("del", 0));
        //审批状态
        customerBoolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        //未收款金额>0
        customerBoolQueryBuilder.filter(rangeQuery(ContractEnum.getAttrConnectData(ContractEnum.UN_FINISH_AMOUNT)).gt(0));
        //非红冲
        customerBoolQueryBuilder.filter(termQuery(ContractEnum.getAttrConnectData(ContractEnum.IS_RED), 0));
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("agg01").field(ContractEnum.getEsAttr4Keyword(ContractEnum.LINK_CUSTOMER)).size(Integer.MAX_VALUE);
        termsAggregationBuilder.executionHint(ElasticConstant.EXECUTION_HINT);
        JSONObject jsonObject = esHelper.multElasticAggs4NoBuckets2Object(indexTypeEnum, customerBoolQueryBuilder, Arrays.asList(termsAggregationBuilder));
        JSONArray buckets = jsonObject.getJSONObject("aggregations").getJSONObject("agg01").getJSONArray("buckets");
        Map<Long,Integer> contractCountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(buckets != null && !buckets.isEmpty()){
            for (Object bucket : buckets) {
                JSONObject bucketJson = (JSONObject)bucket;
                //客户id
                Long customerIdKey = Long.valueOf(bucketJson.get("key").toString());
                //当前客户下满足的合同的个数
                Integer  docCount= bucketJson.getInteger("doc_count");
                contractCountMap.put(customerIdKey,docCount);
            }
        }
        return contractCountMap;
    }

    /**
     * 获取预收款余额的精度
     * @param corpid
     * @param distributorMark
     * @return
     */
    private Integer getAccuracy(String corpid, Integer distributorMark) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(),corpid, distributorMark);
        List<FieldAttrEntity> balanceExplains = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Integer accuracy = 2;
        for (FieldAttrEntity balanceExplain : balanceExplains) {
            if(Objects.equals(balanceExplain.getAttr(), PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr())){
                accuracy = balanceExplain.getAccuracy();
                break;
            }
        }
        return accuracy;
    }
    
    @Override
    public void getSupplementAmount(PaasFormDataEsListVO formDataListVO,String corpid) throws XbbException {
        List<Long> customerId = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( PaasFormDataEntityExt paasFormDataEntityExt : formDataListVO.getPaasFormDataESList() ) {
            customerId.add(paasFormDataEntityExt.getId());
        }
        if ( CollectionsUtil.isNotEmpty(customerId) ) {
            List<PaymentBalanceEntity> paymentBalanceEntityList = paymentBalanceModel.getByCustomerIds(customerId, corpid);
            Map<Long, Double> paymentBalanceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaymentBalanceEntity item:paymentBalanceEntityList) {
                paymentBalanceMap.put(item.getCustomerId(), item.getAdvancePaymentBalance());
            }
            formDataListVO.getPaasFormDataESList().forEach(item-> {
                Double advancePaymentBalance = paymentBalanceMap.get(item.getId()) == null ? 0.00D : paymentBalanceMap.get(item.getId());
                item.setAdvancePaymentBalance(advancePaymentBalance);
            });
        }
    }

    @Override
    public List<PaymentBalanceEntity> updatePaymentBalance4Del(String corpid, Set<String> errorTypeSet, Set<String> errorDataSet, Set<Long> customerIdSet, Map<Long, List<String>> prepaymentNoMap, Map<Long, List<Long>> prepaymentIdMap, List<Long> delIdList, SheetDeleteHandleRelateDTO sheetDeleteHandleRelateDTO) throws XbbException {
        //客户id-该客户要增加/减少的余额
        Map<Long, Double> customerIdToBalance = sheetDeleteHandleRelateDTO.getCustomerIdToBalance();
        List<String> delNoList = sheetDeleteHandleRelateDTO.getDelNoList();
        List<PaymentBalanceEntity> balanceList = paymentBalanceModel.getByCustomerIds(customerIdSet, corpid);
        Iterator<PaymentBalanceEntity> iterator = balanceList.iterator();
        while (iterator.hasNext()) {
            PaymentBalanceEntity balanceEntity = iterator.next();
            Long customerId = balanceEntity.getCustomerId();
            Double oldAdvancePaymentBalance = balanceEntity.getAdvancePaymentBalance();
            Double newAdvancePaymentBalance = customerIdToBalance.getOrDefault(customerId, 0D);
            Double newAmount = Arith.add(newAdvancePaymentBalance, oldAdvancePaymentBalance);
            //更新后的客户余额小于0，则该客户下回款单不能删除
            if(newAmount < BasicConstant.ZERO_DOUBLE){
                //封装不能删除信息，并从delIdList、delNoList移除
                commonHelp.removeInfo4DelError(I18nMessageUtil.getMessage(ErrorMessageConstant.NON_ZERO_ADVANCE_PAYMENT_BALANCE), errorTypeSet, errorDataSet, prepaymentNoMap, prepaymentIdMap, delIdList, delNoList, customerId);
                iterator.remove();
            }
            //updateBatchByCorpidAndCustomerId方法mapper内部已经用原金额加上新的金额，因此此处把新的金额置入即可
            balanceEntity.setAdvancePaymentBalance(newAdvancePaymentBalance);
        }
        return balanceList;
    }

    @Override
    public Integer deleteBatch(List<Long> idIn, String corpid) throws XbbException {
        if(CollectionsUtil.isEmpty(idIn)){
            return 0;
        }
        Integer delete = paymentBalanceModel.deleteBatch(idIn, corpid);
        paymentBalanceUserModel.deleteBatchByParentId(idIn,corpid);
        return delete;
    }

    @Override
    public void updateRollback(List<Long> idIn, String corpid) throws XbbException {
        if(CollectionsUtil.isEmpty(idIn)){
            return;
        }
        paymentBalanceModel.deleteBatchRollback(idIn, corpid);
        paymentBalanceUserModel.deleteBatchRollbackByParentId(idIn,corpid);
    }

    @Override
    public void updateRollbackByCustomerId(Collection<Long> customerIdIn, String corpid) throws XbbException {
        if (CollectionUtils.isEmpty(customerIdIn)) {
            return;
        }
        List<PaymentBalanceEntity> balanceList = paymentBalanceModel.getByCustomerIds(customerIdIn, corpid);
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_PAYMENT_BALANCE;
        if (CollectionsUtil.isNotEmpty(balanceList)) {
            //数据库数据不为空，则把数据库同步至es内
            for (PaymentBalanceEntity balanceEntity : balanceList) {
                InsertDTO insertDTO = paymentBalanceModel.getSaveDTO(balanceEntity, indexTypeEnum);
                paasEsModel.update(insertDTO);
            }
        } else {
            //数据库没有，但是es能查到，则把es内的直接删除
            BoolQueryBuilder boolQueryBuilder = chartQueryHelp.boolQueryBuilder4Base(corpid);
            List<PaymentBalanceEntity> result = formHelp.getFormListByIds4All(indexTypeEnum,boolQueryBuilder, "customerId", customerIdIn, Collections.singletonList(BasicConstant.ID), PaymentBalanceEntity.class);
            if (CollectionsUtil.isNotEmpty(result)) {
                //新建失败，则直接删除es
                List<DeleteDTO> deleteUserList = new ArrayList<>();
                for (PaymentBalanceEntity entity : result) {
                    DeleteDTO deleteDTO = new DeleteDTO();
                    deleteDTO.setEsId(corpid + "_" + entity.getId());
                    deleteDTO.setIndexTypeEnum(indexTypeEnum);
                    deleteUserList.add(deleteDTO);
                }
                paasEsModel.physicalDeleteBatchChild(deleteUserList, corpid, indexTypeEnum);
            }
        }
    }

    /**
     * 批量删除预收款余额
     *（1）首先需要判断预收款详情里面的预付款及其核销记录为空，才能进行删除
     * (2)前置条件满足才能进行删除
     * @param formDataDeleteBatchDTO
     */
    @Override
    public List<Long> deletePaymentBalanceBatch(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        //判断是否满足能进行删除预收款的条件
        //直接调用现成的的方法去做查询，FormDataDeleteBatchDTO转化成PaySheetFromBalanceDTO
        PaymentSheetFromBalanceDTO paymentSheetFromBalanceDTO = new PaymentSheetFromBalanceDTO();
        BeanUtil.copyProperties(formDataDeleteBatchDTO,paymentSheetFromBalanceDTO);

        PaymentBalanceEntity paymentBalanceEntity = paymentBalanceModel.getById(formDataDeleteBatchDTO.getDataIdList().get(0), formDataDeleteBatchDTO.getCorpid());
        if (paymentBalanceEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //获取客户id
        Long customerId = paymentBalanceEntity.getCustomerId();
        paymentSheetFromBalanceDTO.setCustomerId(customerId);
        //设置客户名称
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId, formDataDeleteBatchDTO.getCorpid());
        String customerName = "";
        if(customerEntity != null){
            customerName = customerEntity.getData().getString(CustomerManagementEnum.NAME.getAttr());
        }
        PaymentSheetFromBalanceListVO paymentSheetFromBalanceListVO = paymentBalanceService.paymentSheetFromBalanceList(paymentSheetFromBalanceDTO);
        if (!ObjectUtils.isEmpty(paymentSheetFromBalanceListVO) && CollectionsUtil.isNotEmpty(paymentSheetFromBalanceListVO.getPaasFormDataESList())) {
            throw new XbbException(FundAccountErrorCodeEnum.API_ERROR_1000011);
        }
        //进行实际的预收款删除
        deleteBatch(formDataDeleteBatchDTO.getDataIdList(),formDataDeleteBatchDTO.getCorpid());
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), formDataDeleteBatchDTO.getLoginUserName(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getName(),customerName);
        mongoLogHelp.buildLog(formDataDeleteBatchDTO.getCorpid(), formDataDeleteBatchDTO.getUserId(), formDataDeleteBatchDTO.getLoginUserName(), OperateModuleTypeEnum.PaymentManage, OperateTypeEnum.DELETE,
                formDataDeleteBatchDTO.getDataIdList().get(0).toString(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getName(), memo, formDataDeleteBatchDTO.getHttpHeader());
        return formDataDeleteBatchDTO.getDataIdList();
    }

}
